home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / 48asmdbg.zip / SIM1.C < prev    next >
C/C++ Source or Header  |  1992-04-09  |  16KB  |  396 lines

  1.  
  2.  
  3. /*  SIM1.C: A SATURN TO C CONVERTER... copyright (1990) by Peter Hawkins
  4.  
  5. This programme is hereby placed in the public domain. Not to be sold in
  6. whole or part for financial gain. No liability will be accepted by the
  7. author. Do not remove this copyright notice.
  8.  
  9. Parts of it are not-too-well written, and it produces messy code, but
  10. I don't really care!
  11.  
  12. Peter Hawkins: apm279l@vaxc.cc.monash.edu.au
  13.  
  14. Suggestions/comments/additions welcome.
  15. Flames to: bush@whitehouse.gov
  16.  
  17.  
  18. This version:
  19.                  Long is assumed to be four-byte, so all registers are 2-longs.
  20.                  a,b,c,d,d1,d0,st and p are all 64 bit, but only the relevant
  21.                  nybbles are used.
  22.                  The return-to-RPL address, stack pointer, d and b are
  23.                  used, but are initially set to arbitrary values. A jump to
  24.                  RPL is detected. Other jumps to memory are processed by the
  25.                  routine in labels.h (this allows you to add a table of
  26.                  "known" addresses of ROM subroutines.)
  27.                  The routine will warn you if you jump to RPL without restoring
  28.                  D,B D1 or D0. If you write to memory, this *is not* done,
  29.                  instead, a message is displayed to say what was written and
  30.                  where. Similarly, You are prompted for memory contents when
  31.                  you read from memory *unless* the routine in labels.h detects
  32.                  a read from a "known" location (eg stack).
  33.  
  34.                  The commands sethex and setdec are not implemented yet - all
  35.                  operations are in HEX at this stage. If someone extends this
  36.                  send me a copy. I'd also like copies of any other extensions
  37.                  including additions to the labels.h file. I don't have time to
  38.                  do this stuff myself.
  39.  
  40.                  The hardware status registors are not implemented, nor is IN
  41.                  or OUT; opcodes which use them are ignored.
  42.  
  43.                  The opcodes used are Alonzo's improved set, with one
  44.                  additional command: "show_re[gisters]" which causes the
  45.                  contents of all registers to be printed whenever the programme
  46.                  reaches that point.
  47.  
  48.                  If you select the "printout" mode at the prompt, the source
  49.                  code will behave like a (crudish) debugger. You can step
  50.                  through the "pseudo opcodes" one at a time, or several at a
  51.                  time, alter register contents, and the registors are displayed
  52.                  after each step.
  53.  
  54.                  You've got some self-modifying code? bad luck; won't work
  55.                  sorry - this is a crude debugger - I don't think it's worth
  56.                  allowing for every eventuality at this stage.
  57.  
  58.                  You may want to add to labels.h. Also, the screen functions
  59.                  are set up for a VT100, if you use another sort of terminal,
  60.                  just change the escape sequences (first routines in sim1.h)
  61.  
  62. */
  63.  
  64. #include <stdio.h>
  65. #include <string.h>
  66.  
  67. FILE            *infd, *outfd;
  68. int             inptr =
  69. 0,min,max,i,digit,bufptr,dotpos,ret_count=0,print_mode=0
  70. ;
  71. char            ch,field[4],r1[19],r2[4],buffer[50],label[20];
  72.  
  73. getbuff()
  74. {
  75.   char ch1;
  76.  
  77.   bufptr = 0;
  78.   buffer[bufptr] = 0; /* in case blank line or comment only */
  79.   dotpos = 0;
  80.   while ( (!feof(infd)) && ((ch1=fgetc(infd)) != 10))
  81.   {
  82.     if (ch1 == 59)
  83.     {
  84.       while (fgetc(infd) != 10);
  85.       if (bufptr) break;
  86.     }
  87.     else
  88.     {
  89.       if ((ch1 > 31) || (ch1 == 9)) buffer[bufptr++] = ch1;
  90.       if (ch1 == '.') dotpos = bufptr;
  91.       if( ch1 == ':' )
  92.       {
  93.         fprintf(outfd,"\n");
  94.         buffer[bufptr] = 0;
  95.         fprintf(outfd,"%s\n",buffer);
  96.         if (print_mode) fprintf(outfd,"printf(%c%s\\n%c);\n",34,buffer,34);
  97.         bufptr = 0;
  98.         dotpos = 0;
  99.       }
  100.     }
  101.   }
  102.   while ((bufptr > 0)&&(buffer[bufptr-1] < 33)) bufptr--; /*strip
  103. trailing junk
  104. */
  105.   buffer[bufptr] = 0; /* terminate string */
  106.   bufptr = 0;
  107. }
  108.  
  109. char gtchar() /* finds & returns to next non-junk char, or end of string */
  110. {
  111.   char ch1;
  112.   ch1 = 1;
  113.   while ( (ch1 != 0) && ((ch1=buffer[bufptr++]) < 33 ));
  114.   return ch1;
  115. }
  116.  
  117. int get_token()
  118. {
  119. #define num_3_tokens 18
  120.     static char token_table3[num_3_tokens][3] =
  121.               { "pop","clr","inc","dec","add","sub","and","rln","rrn",
  122.                 "srn","srb","sln","neg","not","nop","brz","ret","or." };
  123.  
  124. #define num_4_tokens 19
  125.     static char token_table4[num_4_tokens][4] =
  126.               { "move","swap","push","clrb","setb","call","jump","breq",
  127.                 "brne","brgt","brlt","brge","brle","brbc","brbs","brcc",
  128.                 "brcs","brnz","retz"};
  129.  
  130. #define num_5_tokens 11
  131.     static char token_table5[num_5_tokens][5] =
  132.               { "reteq","retne","retgt","retlt","retge","retle","retbc",
  133.                 "retbs","retcc","retcs","retnz"};
  134.  
  135. #define num_7_tokens 3
  136.     static char token_table7[num_7_tokens][7] =
  137.               { "retsetc","retclrc","show_re"};
  138.  
  139.     int pos1,token,i;
  140.  
  141.     pos1 = bufptr;
  142.  
  143.     if (dotpos)
  144.     {
  145.       bufptr = dotpos;
  146.       for (i = 0; i < 4; ++i) field[i] = 0;
  147.       field[0]=buffer[bufptr++];
  148.       if ((buffer[bufptr] > 31) && (field[0] < 58) && (buffer[bufptr] <
  149. 58)) field[1] = buffer[bufptr++];
  150.       else if (((field[0] == 'w') && (buffer[bufptr] == 'p')) ||
  151.                ((field[0] == 'x') && (buffer[bufptr] == 's')))
  152.            field[1] = buffer[bufptr++];
  153.       else if (field[0] == 'p')
  154.       {
  155.         i = 1;
  156.         while (buffer[bufptr] > 31) field[i++] = buffer[bufptr++];
  157.       }
  158.     }
  159.     else strcpy(field,"def");
  160.  
  161.     token = -1;
  162.     for (i = 0; i < num_7_tokens; ++i)
  163.       { if (!strncmp(&buffer[pos1],&token_table7[i][0],7)) token
  164. =i+num_5_tokens
  165. +num_4_tokens+num_3_tokens; }
  166.     if (token >= 0)
  167.     {
  168.       if (!dotpos) bufptr += 7;
  169.       return (token);
  170.     }
  171.  
  172.     for (i = 0; i < num_5_tokens; ++i)
  173.       { if (!strncmp(&buffer[pos1],&token_table5[i][0],5)) token
  174. =i+num_4_tokens
  175. +num_3_tokens; }
  176.     if (token >= 0)
  177.     {
  178.       if (!dotpos) bufptr += 5;
  179.       return (token);
  180.     }
  181.  
  182.     for (i = 0; i < num_4_tokens; ++i)
  183.       { if (!strncmp(&buffer[pos1],&token_table4[i][0],4)) token =i+num_3_tokens; }
  184.     if (token >= 0)
  185.     {
  186.       if (!dotpos) bufptr += 4;
  187.       return (token);
  188.     }
  189.  
  190.     token = 99;
  191.     for (i = 0; i < num_3_tokens; ++i)
  192.       { if (!strncmp(&buffer[pos1],&token_table3[i][0],3)) token = i; }
  193.     if (!dotpos) bufptr += 3;
  194.     return (token);
  195. }
  196.  
  197.  
  198. main()
  199. {
  200.     char            filenm[20],pr_ans;
  201.     int             tokn;
  202.  
  203.     printf("Input file name> ");
  204.     scanf("%s",filenm);
  205.  
  206.     if(!(infd = fopen(filenm,"r")))
  207.     {
  208.         printf("error opening %s as input\n",filenm);
  209.         exit(0);
  210.     }
  211.     printf("Output file name> ");
  212.     scanf("%s",filenm);
  213.     outfd = fdopen(creat(filenm,0),"w");
  214.     printf("Do you want %s to step through? n/y:",filenm);
  215.     scanf("%s",&pr_ans);
  216.     if (pr_ans == 'y' || pr_ans == 'Y') print_mode=1;
  217.  
  218.     fprintf(outfd,"#include %csim1.h%c\n\nmain()\n{\n\n#include%clabels.h%c\nset_pmasks();\n\ncls();\n\n",34,34,34,34);
  219.  
  220.     while (!feof(infd))
  221.     {
  222.       getbuff();
  223.       if (gtchar())
  224.       {
  225.         bufptr--;
  226.         if (print_mode) fprintf(outfd,"getstep(%c%s%c);\n",34,buffer,34);
  227.         switch (tokn = get_token())
  228.         {
  229.         case 0: {fprintf(outfd,"pop();"); break;}
  230.         case 1: {getr1(); fprintf(outfd,"clr(mask_%s,%s);",field,r1); break;}
  231.         case 2: {getr1(); fprintf(outfd,"inc(mask_%s,%s);",field,r1); break;}
  232.         case 3: {getr1(); fprintf(outfd,"dec(mask_%s,%s);",field,r1); break;}
  233.         case 4: {getr1r2();
  234. fprintf(outfd,"add(mask_%s,%s,%s);",field,r1,r2); break;}
  235.         case 5: {getr1r2();
  236. fprintf(outfd,"sub(mask_%s,%s,%s);",field,r1,r2); break;}
  237.         case 6: {getr1r2();
  238. fprintf(outfd,"and(mask_%s,%s,%s);",field,r1,r2); break;}
  239.         case 7: {getr1(); fprintf(outfd,"rln(mask_%s,%s);",field,r1); break;}
  240.         case 8: {getr1(); fprintf(outfd,"rrn(mask_%s,%s);",field,r1); break;}
  241.         case 9: {getr1(); fprintf(outfd,"srn(mask_%s,%s);",field,r1); break;}
  242.         case 10: {getr1(); fprintf(outfd,"srb(mask_%s,%s);",field,r1); break;}
  243.         case 11: {getr1(); fprintf(outfd,"sln(mask_%s,%s);",field,r1); break;}
  244.         case 12: {getr1(); fprintf(outfd,"neg(mask_%s,%s);",field,r1); break;}
  245.         case 13: {getr1(); fprintf(outfd,"not(mask_%s,%s);",field,r1); break;}
  246.         case 14: break;
  247.     case 15: {getr1(); getlbl(); fprintf(outfd,"if (!(%s[0] & mask_%s[0]) ||(!(%s[1] & mask_%s[1]))) {carry=1; goto %s;} else carry=0;\n",r1,field,r1,field,label); break;}
  248.         case 16: {fprintf(outfd,"goto goreturn;"); break;}
  249.         case 17: {getr1r2();
  250. fprintf(outfd,"or(mask_%s,%s,%s);",field,r1,r2); break;}
  251.         case 18:
  252.           {
  253.             getr1r2();
  254.         if (!strcmp(r2,"pc")) fprintf(outfd,"return_flag=0;tmp[1]=%s[1]&mask_a[1]; goto jump_mem;",r1);
  255.             else
  256.             {
  257.               if (r1[0] == '@')
  258. fprintf(outfd,"input(%c%s%c,mask_%s,%s,%s);",34,
  259. field,34,field,&r1[1],r2);
  260.           else if (r2[0] == '@') fprintf(outfd,"output(%c%s%c,mask_%s,%s,%s);",34,field,34,field,r1,&r2[1]);
  261.               else fprintf(outfd,"move(mask_%s,%s,%s);",field,r1,r2);
  262.             }
  263.             break;
  264.           }
  265.         case 19:
  266.           {
  267.             getr1r2();
  268.             if (r1[0] == '@')
  269.             {
  270.           fprintf(outfd,"input(%c%s%c,mask_%s,%s,tmp);",34,field,34,field,&r1[1]);
  271.               strcpy(r1,"tmp");
  272.             }
  273.             if (r2[0] == '@')
  274.             {
  275.           fprintf(outfd,"input(%c%s%c,mask_%s,tmp,%s);",34,field,34,field,&r2[1]);
  276.               strcpy(r2,"tmp");
  277.             }
  278.             fprintf(outfd,"swap(mask_%s,%s,%s);",field,r1,r2);
  279.             break;
  280.           }
  281.         case 20: {fprintf(outfd,"push();"); break;}
  282.     case 21: {getr1r2();fprintf(outfd,"%s[1]=%s[1]&(~(1L<<(%s[1]&mask_1[1])));",r2,r2,r1); break;}
  283.     case 22: {getr1r2();fprintf(outfd,"%s[1]=%s[1]|(1L<<(%s[1]&mask_1[1]));",r2,r2,r1); break;}
  284.     case 23: {getlbl(); fprintf(outfd,"stack[stkptr--] = 0X%05X; goto%s; ret_%05X:",ret_count,label,ret_count); ret_count++; break;}
  285.         case 24: {getlbl(); fprintf(outfd,"goto %s;",label); break;}
  286.         case 25: {getr1r2(); getlbl(); branch("==",label); break;}
  287.         case 26: {getr1r2(); getlbl(); branch("!=",label); break;}
  288.         case 27: {getr1r2(); getlbl(); branch("> ",label); break;}
  289.         case 28: {getr1r2(); getlbl(); branch("< ",label); break;}
  290.         case 29: {getr1r2(); getlbl(); branch(">=",label); break;}
  291.         case 30: {getr1r2(); getlbl(); branch("<=",label); break;}
  292.     case 31: {getr1r2(); getlbl(); fprintf(outfd,"if((~%s[1])&(1L<<(%s[1]&mask_1[1]))) {carry=1; goto %s;} else carry=0;",r2,r1,label); break;}
  293.     case 32: {getr1r2(); getlbl(); fprintf(outfd,"if(%s[1]&(1L<<(%s[1]&mask_1[1]))) {carry=1; goto %s;} else carry=0;",r2,r1,label); break;}
  294.     case 33: {getlbl(); fprintf(outfd,"if (!carry) goto %s;",label);break;}
  295.     case 34: {getlbl(); fprintf(outfd,"if (carry) goto %s;",label); break;}
  296.     case 35: {getr1(); getlbl(); fprintf(outfd,"if((%s[0]&mask_%s[0])||(%s[1]&mask_%s[1])) {carry=1; goto %s;} else carry=0;",r1,field,r1,field,label); break;}
  297.     case 36: {getr1(); fprintf(outfd,"if (!(%s[0] & mask_%s[0]) ||!(%s[1] & mask_%s[1]))) {carry=1; goto %s;} else carry=0;",r1,field,r1,field); break;}
  298.         case 37: {getr1r2(); branch("==","goreturn"); break;}
  299.         case 38: {getr1r2(); branch("!=","goreturn"); break;}
  300.         case 39: {getr1r2(); branch("> ","goreturn"); break;}
  301.         case 40: {getr1r2(); branch("< ","goreturn"); break;}
  302.         case 41: {getr1r2(); branch(">=","goreturn"); break;}
  303.         case 42: {getr1r2(); branch("<=","goreturn"); break;}
  304.     case 43: {getr1r2(); fprintf(outfd,"if((~%s[1])&(1L<<(%s[1]&mask_1[1]))) {carry=1; goto goreturn;} else carry=0;",r2,r1); break;}
  305.     case 44: {getr1r2(); fprintf(outfd,"if(%s[1]&(1L<<(%s[1]&mask_1[1]))) {carry=1; goto goreturn;} else carry=0;",r2,r1); break;}
  306.         case 45: {fprintf(outfd,"if (!carry) goto goreturn;"); break;}
  307.         case 46: {fprintf(outfd,"if (carry) goto goreturn;"); break;}
  308.     case 47: {getr1(); fprintf(outfd,"if ((%s[0] &mask_%s[0])||(%s[1] & mask_%s[1])) {carry=1; goto goreturn;} else carry=0;",r1,field,r1,field); break;}
  309.         case 48: {fprintf(outfd,"carry=1; goto goreturn;"); break;}
  310.         case 49: {fprintf(outfd,"carry=0; goto goreturn;"); break;}
  311.     case 50: {fprintf(outfd,"printf(%c\\n%c); show_regs();",34,34); break;}default: fprintf(outfd,"printf(%cUnknown operation:%s\\n%c);",34,buffer,34);}if (!print_mode) fprintf(outfd,"%c/* %s */\n",9,buffer);}}
  312.     if (ret_count){fprintf(outfd,"\n\ngoreturn: switch(stack[++stkptr] & mask_a[1])\n{\n");
  313.     for (i = 0;i < ret_count; ++i) fprintf(outfd,"    case 0X%05X: goto ret_%05X;\n",i,i);fprintf(outfd,"    case 0xfffff: {printf(%cERROR: you'vepushed/popped return stack\\n%c); exit(0);}\n",34,34);
  314.     fprintf(outfd,"  }\n\n");
  315.     }
  316.  
  317.     fprintf(outfd,"}\n");
  318.     fflush(outfd);
  319.     fclose(outfd);
  320.     fclose(infd);
  321. }
  322.  
  323. getr1()
  324. {
  325.  int j;
  326.  char ch1;
  327.  
  328.  for (j = 0; j < 4; j++) r1[j] = 0;
  329.  ch1=gtchar();
  330.  for (j = 0; ((ch1 != ',') && (j < 3)); j++) {r1[j] = ch1; ch1=gtchar();}
  331. }
  332.  
  333. getr1r2()
  334. {
  335.   int j,k;
  336.   char ch1;
  337.  
  338.   for (j = 0; j < 19; j++) r1[j] = 0;
  339.   for (j = 0; j < 4 ; j++) r2[j] = 0;
  340.   ch1=gtchar();
  341.   for (j = 0; ch1 != ','; j++) {r1[j] = ch1; ch1=gtchar();}
  342.  
  343.   if (r1[0] < 58) /* constant (not register) */
  344.   {
  345.     if ( (r1[0] == '$') || (r1[0] == '#') )fprintf(outfd,"constmp(mask_%s,0x%sL); ",field,&r1[1]);
  346.     else fprintf(outfd,"constmp(mask_%s,%sL); ",field,r1);
  347.     strcpy(r1,"tmp");
  348.     r1[3] = 0;
  349.   }
  350.  
  351.   ch1=gtchar();
  352.   for (j = 0; ((ch1 > 0) && (ch1 != ',') && (j < 3)); j++) {r2[j] = ch1;ch1=gtchar();}}
  353.  
  354. getlbl()
  355. {
  356.   int lblptr;
  357.   char ch1;
  358.   if ((ch1 = gtchar()) == 64)
  359.   {
  360.     strcpy(label,"_at_");
  361.     lblptr = 4;
  362.   }
  363.   else
  364.   {
  365.     lblptr = 0;
  366.     bufptr--;
  367.   }
  368.   strcpy(&label[lblptr],&buffer[bufptr]);
  369. }
  370.  
  371.  
  372. branch( char *condit, char *lbl)
  373. {
  374.   if (!strcmp(condit,"=="))
  375.   {
  376.     fprintf(outfd,"if(((%s[0]&mask_%s[0])%s(%s[0]&mask_%s[0]))&&",r1,field,condit,r2,field);
  377.     fprintf(outfd,"((%s[1]&mask_%s[1])%s(%s[1]&mask_%s[1])))",r1,field,condit,r2,field);}
  378.   else if (!strcmp(condit,"!="))
  379.   {
  380.     fprintf(outfd,"if(((%s[0]&mask_%s[0])%s(%s[0]&mask_%s[0]))||",r1,field,condit,r2,field);
  381.     fprintf(outfd,"((%s[1]&mask_%s[1])%s(%s[1]&mask_%s[1])))",r1,field,condit,r2,field);}
  382.   else if ((!strcmp(condit,">="))||(!strcmp(condit,"<=")))
  383.   { /* ruddy heck!! what a test!! any better ideas???? */
  384.     fprintf(outfd,"if ((((mask_%s[0]) && ((%s[0]&mask_%s[0])%1s(%s[0]&mask_%s[0])))||",field,r1,field,condit,r2,field);fprintf(outfd,"((!mask_%s[0]) &&((%s[1]&mask_%s[1])%1s(%s[1]&mask_%s[1]))))",field,r1,field,condit,r2,field);
  385.     fprintf(outfd,"||(((%s[0]&mask_%s[0])==(%s[0]&mask_%s[0]))&&",r1,field,r2,field);
  386.     fprintf(outfd,"((%s[1]&mask_%s[1])==(%s[1]&mask_%s[1]))))",r1,field,r2,field);
  387.   }
  388.   else
  389.   {
  390.     fprintf(outfd,"if (((mask_%s[0]) && ((%s[0]&mask_%s[0])%s(%s[0]&mask_%s[0])))||",field,r1,field,condit,r2,field);
  391.     fprintf(outfd,"((!mask_%s[0]) && ((%s[1]&mask_%s[1])%s(%s[1]&mask_%s[1]))))",field,r1,field,condit,r2,field);
  392.   }
  393.   fprintf(outfd,"{carry=1; goto %s;} else carry=0;",lbl);
  394. }
  395.  
  396.